package com.tbit.uqbike.service.business.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tbit.common.entity.view.Result;
import com.tbit.uqbike.constant.RedisConstant;
import com.tbit.uqbike.constant.SysConstant;
import com.tbit.uqbike.constant.UserConstant;
import com.tbit.uqbike.enums.SystemCodeEnum;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.business.PageData;
import com.tbit.uqbike.object.business.Point;
import com.tbit.uqbike.object.pojo.*;
import com.tbit.uqbike.object.pojo.dto.AccountUserDTO;
import com.tbit.uqbike.object.pojo.vo.AccountUserLoginExportVO;
import com.tbit.uqbike.object.pojo.vo.BatchOperationMsgVO;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.service.base.CalibrateService;
import com.tbit.uqbike.service.base.RedisService;
import com.tbit.uqbike.service.base.TokenService;
import com.tbit.uqbike.service.business.AccountService;
import com.tbit.uqbike.service.business.AccountUserService;
import com.tbit.uqbike.service.business.HolderAccountBoundService;
import com.tbit.uqbike.service.business.RoleService;
import com.tbit.uqbike.service.rpcservice.PurviewService;
import com.tbit.uqbike.webmanager.dao.core.*;
import com.tbit.uqbike.webmanager.util.LogUtil;
import com.tbit.uqbike.webmanager.util.MD5PasswordUtil;
import com.tbit.utils.DateTimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author MyWin E-mail:335918956@qq.com
 * @version 1.0
 * @createTime 2020-01-03 16:28
 */
@Service
@Slf4j
public class AccountUserServiceImpl implements AccountUserService {
    @Autowired
    private AccountDao accountDao;
    @Autowired
    private AccountService accountService;
    @Autowired
    private AccountUserDao accountUserDao;
    @Autowired
    private PurviewService purviewService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private GeoRegionBoundDao geoRegionBoundDao;
    @Autowired
    private GeoRegionDao geoRegionDao;
    @Autowired
    private CalibrateService calibrateService;
    @Autowired
    private RedisService redisService;
    @Resource
    private HolderAccountBoundService holderAccountBoundService;
    @Autowired
    private RoleService roleService;
    @Resource
    private RoleDao roleDao;

//    @Override
//    public PageData<List<AccountUser>> getAccountUserList(LoginInfo li, Integer accountId, Integer rowCount, Integer pageNO) {
//        if (!purviewService.purviewCheck(li.id, accountId)) {
//            throw new BaseException(SystemCodeEnum.NO_PRIVILEGE);
//        }
//        Map<String, Object> map = new HashMap<>();
//        map.put("accountId", accountId);
//        boolean page = null != rowCount && null != pageNO;
//        if (page) {
//            map.put("start", rowCount * (pageNO - 1));
//            map.put("rowCount", rowCount);
//        }
//        List<AccountUser> accountUserList = accountUserDao.getAccountUserByAid(map);
//        List<List<GeoRegion>> geoList=new ArrayList<>();
//
//        for (AccountUser accountUser : accountUserList) {
//            List<GeoRegion> geoRegions= geoRegionDao.getById(accountUser.getAccountUserId());
//            geoList.add(geoRegions);
//        }
//
//        Integer total = accountUserDao.getAccountUserCntByAid(map);
//        return new PageData<>(accountUserList, total);
//    }

    /**
     * 3.0.0修改的方法
     *
     * @return
     */
    @Override
    public PageData<List<AccountUserDTO>> getAccountUserLists(LoginInfo li, Integer accountId, Integer rowCount, Integer pageNO, String phone, String name) {
        if (!purviewService.purviewCheck(li.id, accountId)) {
            throw new BaseException(SystemCodeEnum.NO_PRIVILEGE);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("accountId", accountId);
        map.put("phone", phone);
        map.put("name", name);
        boolean page = null != rowCount && null != pageNO;
        if (page) {
            map.put("start", rowCount * (pageNO - 1));
            map.put("rowCount", rowCount);
        }
        List<AccountUserDTO> accountUserList = accountUserDao.getAccountUserByAids(map);

        Account account = accountService.getById(accountId);
        Map<Integer, Role> roleMap = roleDao.selectRoleAll().stream().collect(Collectors.toMap(Role::getRoleId, role -> role));
        for (AccountUserDTO accountUser : accountUserList) {
            List<GeoRegion> geoRegions = geoRegionDao.getById(accountUser.getAccountUserId());
            accountUser.setGeoRegions(geoRegions);
            /**填充角色名称*/
            if (accountUser.getSubRoleType() == 0){
                accountUser.setSubRoleName(roleMap.get(account.getType()).getRoleName());
            }else {
                Integer subRoleType = subRoleTypeToRoleId(accountUser.getSubRoleType());
                accountUser.setSubRoleName(roleMap.get(subRoleType).getRoleName());
            }
        }


        Integer total = accountUserDao.getAccountUserCntByAid(map);
        return new PageData<>(accountUserList, total);
    }

    @Override
    public List<AccountUserLastPos> getAccountUserPointTime(Integer accountId) {
        List<AccountUserLastPos> accountUserPointList = accountUserDao.getAccountUserPointTime(accountId);
        for (AccountUserLastPos accountUserLastPos : accountUserPointList) {
            if (null != accountUserLastPos.getLat() && null != accountUserLastPos.getLon()) {
                /**经纬度校准*/
                Point point = calibrateService.calibrateOffSet(accountUserLastPos.getLon(), accountUserLastPos.getLat(), SysConstant.GOOGLE);
                accountUserLastPos.setLoC(point.getX());
                accountUserLastPos.setLaC(point.getY());
            }
        }
        return accountUserPointList;
    }


    @Override
    public List<AccountUserLoginExportVO> queryAccountUserByAccountId(Integer accountId, Integer type) {
        return accountUserDao.queryAccountUserByAccountId(accountId, type);
    }

    @Override
    public void addAccountUser(LoginInfo li, Integer accountId, Integer subRoleType, AccountUser accountUser, String expireDate, List<Integer> regionIdList) {
        if (!purviewService.purviewCheck(li.id, accountId)) {
            throw new BaseException(SystemCodeEnum.NO_PRIVILEGE);
        }
        Map<String, Object> geoRegionBoundList = new HashMap<>();
        if (regionIdList.size() > 0) {
            geoRegionBoundList.put("regionId", regionIdList);
        }
        geoRegionBoundList.put("accountUserId", accountUser.getAccountUserId());
        Integer geoRegionBounds = geoRegionBoundDao.getByReginonIdAndUserId(geoRegionBoundList);

        // 查询此区域的品牌编号
        Integer brandId = accountService.getBrandIdByAccountId(accountId);

        Map<String, Object> params = new HashMap<>();
        params.put("phone", accountUser.getPhone());
        params.put("country", accountUser.getCountry());
        params.put("brandId", brandId);

        AccountUser accountUserExist = accountUserDao.getByPhone(params);

        /*if(accountUserExist!=null){
            throw new BaseException("user_have_exist");
        }*/
        if (accountUserExist == null) {
            // 插入
            accountUser.setJoinTime(new Date());
            accountUser.setUpdateTime(new Date());
            accountUserDao.insert(accountUser);
            accountUserExist = accountUser;
        }


        if (geoRegionBounds == 0) {
            GeoRegionBound geoRegionBound = new GeoRegionBound();
            for (Integer regionId : regionIdList) {
                geoRegionBound.setAccountId(accountId);
                geoRegionBound.setRegionId(regionId);
                geoRegionBound.setAccountUserId(accountUserExist.getAccountUserId());
                geoRegionBound.setBoundTime(new Date());
                geoRegionBound.setIsLeader(0);
                geoRegionBoundDao.insert(geoRegionBound);
            }
        }


        Map<String, Object> map = new HashMap<>();
        map.put("accountUserId", accountUserExist.getAccountUserId());
        map.put("accountId", accountId);
        map.put("brandId", brandId);
        map.put("addTime", new Date());
        map.put("expireDate", expireDate);
        map.put("subRoleType", subRoleType);
        // 判定一下绑定关系是否存在
        List<AccountUserBound> accountUserTemp = accountUserDao.getByAccountUserId(accountUserExist.getAccountUserId());
        if (CollUtil.isEmpty(accountUserTemp)) {
            accountUserDao.insertAndUidBound(map);
        } else {
            Account account = accountService.getById(brandId);
            throw new BaseException(String.format("用户已经存在：%s", account.getName()));
        }
    }

    @Override
    public void delAccountUser(LoginInfo li, Integer accountId, Integer accountUserId) {
        if (!purviewService.purviewCheck(li.id, accountId)) {
            throw new BaseException(SystemCodeEnum.NO_PRIVILEGE);
        }
        List<Integer> regionId = new ArrayList<>();
        List<GeoRegion> geoRegions = geoRegionDao.getById(accountUserId);
        for (GeoRegion geoRegion : geoRegions) {
            regionId.add(geoRegion.getRegionId());
        }
        Map<String, Object> map = new HashMap<>();
        map.put("accountId", accountId);
        map.put("accountUserId", accountUserId);
        Account account = accountService.getById(accountId);
        if (UserConstant.USER_AGENT.equals(account.getType()) || UserConstant.USER_FRANCHISEE.equals(account.getType())) {
            Integer brandId = accountService.getBrandId(accountId);
            map.put("brandId", brandId);
        } else {
            map.put("brandId", accountId);
        }
        Map<String, Object> params = new HashMap<>();
        params.put("regionId", regionId);
        params.put("accountUserId", accountUserId);
        AccountUser accountUser = accountUserDao.getAccountUserByAidAndUid(map);
        if (null != accountUser) {
            if (accountUser.isDel()) {
                throw new BaseException("请勿重复删除");
            }
            //调整为逻辑删除
            accountUserDao.del(accountUserId);
            tokenService.destroyToken(new LoginInfo(accountUserId));
            //删除账号同时删除账号和角色绑定关系
            accountUserDao.delAndUidBound(map);
            //删除运维端token
            try {
                destroyMainToken(accountUserId, accountId);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                LogUtil.warn("删除运维端token失败,accountUserId=" + accountUserId);
            }
            // 如果解除的是当前登录的，需要配置session失效
           /* if (Objects.equals(li.id, accountId) && Objects.equals(li.accountUserId, accountUserId)) {
                tokenService.destroyToken(li);
            }*/
        }
    }

    @Override
    //@Transactional
    public void modAccountUser(LoginInfo li, AccountUser accountUser, List<Integer> regionIdList) {
        Integer accountUserId = accountUser.getAccountUserId();
        Map<String, Object> map = new HashMap<>();
        map.put("accountId", li.id);
        if (accountUserId == null) {
            accountUserId = li.accountUserId;
        }

        // 鉴权
        map.put("accountUserId", accountUserId);
        AccountUserBound accountUserBoundDB = accountUserDao.getByUserId(map);
        if (accountUserBoundDB != null) {
            /**如果修改人身份是股东，不许修改*/
            if (accountUserBoundDB.getSubRoleType().equals(UserConstant.USER_CUS_HOLDER)) {
                throw new BaseException("ver.holder.can.not.update");
            }
        }
        AccountUser accountUserById = accountUserDao.getAccountUserById(accountUserId);
        if (accountUserById != null && accountUserById.isDel()) {
            throw new BaseException("已删除账号不允许修改");
        }
//        if (!Objects.equals(li.type, UserConstant.USER_ADMIN) && !Objects.equals(li.type, UserConstant.USER_BRAND)
//                && !Objects.equals(li.type, UserConstant.USER_FRANCHISEE)
//        ) {
//            Account account = Optional.of(accountUserDao.getByAccountUserId(accountUser.getAccountUserId()))
//                    .filter(CollectionUtils::isNotEmpty)
//                    .map(x -> x.get(0)).map(AccountUserBound::getAccountId)
//                    .map(accountDao::getByAccountId)
//                    .orElse(null);
//            if (account == null || !Objects.equals(account.getParentId(), li.id)) {
//                throw new BaseException(SystemCodeEnum.NO_PRIVILEGE);
//            }
//        }
        accountUser.setAccountUserId(accountUserId);
        accountUser.setUpdateTime(new Date());

        /**修改到期时间*/
        if (accountUser.getExpireDate() != null || accountUser.getSubRoleType() != null) {
            AccountUserBound accountUserBound = new AccountUserBound();
            accountUserBound.setAccountUserId(accountUserId);
            accountUserBound.setSubRoleType(accountUser.getSubRoleType());
            accountUserBound.setExpireDate(accountUser.getExpireDate());
            accountUserDao.editExpire(accountUserBound);
        }
        // 更新
        accountUserDao.update(accountUser);

        geoRegionBoundDao.deleteByUserId(accountUserId);
        List<AccountUserBound> accountUsers = accountUserDao.getByAccountUserId(accountUserId);
        Integer accountId = null;
        for (AccountUserBound user : accountUsers) {
            accountId = user.getAccountId();
        }

        GeoRegionBound geoRegionBound = new GeoRegionBound();
        for (Integer regionId : regionIdList) {
            geoRegionBound.setAccountId(accountId);
            geoRegionBound.setRegionId(regionId);
            geoRegionBound.setAccountUserId(accountUserId);
            geoRegionBound.setBoundTime(new Date());
            geoRegionBound.setIsLeader(0);
            geoRegionBoundDao.insert(geoRegionBound);
        }
        //重置过期校验
        resetExpireCheck(accountUserId);
    }

    @Override
    public List<AccountUser> getByType(Integer accountId, Boolean flag) {
        return accountUserDao.getByType(accountId, flag);
    }


    @Override
    public AccountUserBound getByUserId(Integer accountId, Integer accountUserId) {
        Map<String, Object> map = new HashMap<>();
        map.put("accountId", accountId);
        map.put("accountUserId", accountUserId);
        return accountUserDao.getByUserId(map);
    }

    @Override
    public String getAccountIdByPhone(Integer brandId, String phone, String name) {
        if (phone == null && name == null) {
            throw new BaseException("请输入至少一个搜索条件");
        }
        StringBuilder stringBuffer = new StringBuilder();
        List<Integer> accountIds = accountUserDao.getAccountIdByBrandIdAndPhoneAndName(brandId, phone, name)
                .stream().distinct().collect(Collectors.toList());
        boolean flag = false;
        for (Integer accountId : accountIds) {
            if (flag) {
                //根据名称查询会有多个结果，添加换行符
                stringBuffer.append("<br />");
            }
            if (accountId != null) {
                Account account = accountDao.getByAccountId(accountId);
                if (account != null) {
                    if (account.getType().equals(UserConstant.USER_BRAND)) {
                        stringBuffer.append("• ").append(account.getName());
                    } else if (account.getType().equals(UserConstant.USER_FRANCHISEE)) {
                        /**加盟商继续查询上一级*/
                        Account accountFR = accountDao.getByAccountId(account.getParentId());
                        if (accountFR != null) {
                            stringBuffer.append("• ").append(accountFR.getName()).append("-->");
                        }
                        stringBuffer.append(account.getName());
                    } else if (account.getType().equals(UserConstant.USER_AGENT)) {
                        /**加盟商继续查询上一级*/
                        Account accountFR = accountDao.getByAccountId(account.getParentId());
                        if (accountFR != null) {
                            /**代理商继续查询上一级*/
                            Account accountAG = accountDao.getByAccountId(accountFR.getParentId());
                            if (accountAG != null) {
                                stringBuffer.append("• ").append(accountAG.getName()).append("-->");
                            }
                            stringBuffer.append(accountFR.getName()).append("-->");
                            stringBuffer.append(account.getName());
                        }
                    }
                }
            }
            flag = true;
        }
        return stringBuffer.toString();
    }

    @Override
    public List<AccountUser> getByUserType(Integer accountId, Integer subRoleType) {
        Map<String, Object> map = new HashMap<>();
        map.put("subRoleType", subRoleType);
        map.put("accountId", accountId);
        return accountUserDao.getByUserType(map);
    }

    @Override
    public AccountUser getAccountUserById(Integer accountUserId) {
        return accountUserDao.getAccountUserById(accountUserId);
    }

    @Override
    public void expireCheck(Integer accountUserId) {
        /**判断账号是否过期*/
        String key = RedisConstant.ACCOUNT_USER_EXPIRE_DATE + accountUserId;
        String expireDate = redisService.get(key);
        if (expireDate == null) {
            AccountUserBound accountUserBound = accountUserDao.getBoundByUserId(accountUserId);
            expireDate = accountUserBound == null ? "" : accountUserBound.getExpireDate();
            redisService.add(key, expireDate, 3600);
        }

        if (StrUtil.isNotBlank(expireDate)) {
            if (DateTimeUtil.StringToDateTime(expireDate + " 23:59:59").getTime() <= System.currentTimeMillis()) {
                throw new BaseException(SystemCodeEnum.TOKEN_EXPIRE);
            }
        }
    }

    @Override
    public void resetExpireCheck(Integer accountUserId) {
        String key = RedisConstant.ACCOUNT_USER_EXPIRE_DATE + accountUserId;
        redisService.del(key);
    }

    @Override
    public void updatePassword(String token, Integer accountUserId, String password) {
        LoginInfo loginInfo = tokenService.getLoginInfo(token);
        AccountUser accountUser = accountUserDao.getAccountUserById(accountUserId);
        if (accountUser == null) {
            throw new BaseException("账号不存在");
        }
        //非管理员，需要校验是不是同一个品牌的账号之间进行修改
        if (!loginInfo.roleIsAdmin()) {
            AccountUserBound accountUserBound = accountUserDao.getBoundByUserId(accountUserId);
            Integer brandId = accountService.getBrandId(accountUserBound.getAccountId());
            if (!brandId.equals(loginInfo.getId()) && !accountUserBound.getAccountId().equals(loginInfo.getId())) {
                throw new BaseException("无权操作");
            }
        }
        accountUserDao.updatePassword(accountUserId, MD5PasswordUtil.MD5("QTEDHAJCKIUDcnd." + password));
    }

    /**
     * 批量修改账号角色
     *
     * @param phoneList   手机号
     * @param subRoleType 0:默认值 1:区域运维管理员 2:区域运维人员 6:区域客服 7:股东
     * @param accountId   品牌、加盟商、区域
     * @param roleLevel   1:品牌 2:加盟商 3:区域
     * @return result
     */
    @Override
    public Result<BatchOperationMsgVO<String>> batchUpdateUserRole(String phoneList, Integer subRoleType, Integer brandId, Integer accountId, Integer roleLevel) {
        //获取对应角色列表
        Role role = new Role();
        role.setAccountId(brandId);
        role.setRoleLevel(roleLevel.toString());
        List<Role> roleList = roleDao.selectRoleList(role);

        if (CollectionUtil.isEmpty(roleList)) {
            return Result.error("获取对应角色列表信息失败");
        }

        //校验要修改的角色是否在对应等级下
        if (roleList.stream().map(Role::getRoleCode).noneMatch(subRoleType.toString()::equals)) {
            return Result.error("无权操作");
        }

        BatchOperationMsgVO<String> resultVo = new BatchOperationMsgVO<>();
        Set<String> list = Arrays.stream(phoneList.split(",")).collect(Collectors.toSet());
        //获取绑定的手机号列表
        Map<String, Object> map = new HashMap<>();
        map.put("accountId", accountId);
        List<AccountUserDTO> accountUserByAids = accountUserDao.getAccountUserByAids(map);

        //提取可以修改角色的手机号列表
        List<String> canChangePhoneList = accountUserByAids.stream()
                .map(AccountUserDTO::getPhone)
                .collect(Collectors.toList());

        //分离成功和失败的手机号
        List<String> successList = list.stream()
                .filter(canChangePhoneList::contains)
                .collect(Collectors.toList());

        List<String> failList = list.stream().
                filter(phone -> !canChangePhoneList.contains(phone))
                .collect(Collectors.toList());

        //批量修改账号角色
        if (CollectionUtil.isNotEmpty(successList)) {
            accountUserDao.batchUpdateRole(successList, subRoleType);
        }
        resultVo.setFailList(failList);
        resultVo.setSuccessList(successList);
        return Result.success(resultVo);
    }


    /**
     * 获取区域直属上级账号
     *
     * @param accountId 区域id
     * @param loginInfo 登录信息
     * @return List
     */
    @Override
    public Result<Object> getParentsAccountUser(Integer accountId, LoginInfo loginInfo) {
        List<Integer> accountIds = new ArrayList<>();
        //当前登录账号是否绑定区域
        if (CollectionUtil.isNotEmpty(holderAccountBoundService.getAccountByUserId(loginInfo.getAccountUserId()))) {
            accountIds.add(accountId);
            return Result.success(accountUserDao.getByAccountIds(accountIds));
        }
        accountIds.add(accountId);
        if (UserConstant.USER_ADMIN.equals(loginInfo.type) || UserConstant.USER_BRAND.equals(loginInfo.type)) {
            accountIds.addAll(accountDao.selectAccountAndParentId(accountId));
        } else if (UserConstant.USER_FRANCHISEE.equals(loginInfo.type)) {
            accountIds.add(accountDao.selectParentId(accountId));
        }

        //获取账号信息
        List<AccountUser> accountUserList = accountUserDao.getByAccountIds(accountIds);
        return Result.success(accountUserList);
    }

    /**
     * 删除运维端token(这里比较麻烦，要根据运维端设置token的逻辑来)
     *
     * @param accountUserId 账户id
     * @param accountId     品牌/加盟商/区域  id
     */
    private void destroyMainToken(Integer accountUserId, Integer accountId) {
        Integer accountType = accountDao.getByAccountId(accountId).getType();
        log.info("删除运维端token,accountUserId={},accountType={},accountId={}", accountUserId, accountType, accountId);
        //用户对应的token
        String userKey = RedisConstant.REDIS_ACCOUNT_USER_TOKEN_LIST + accountType + "." + accountUserId;
        //清空list
        List<String> userTokenList = new LinkedList<>();
        try {
            userTokenList = redisService.getList(userKey);
        } catch (SerializationException error) {
            redisService.del(userKey);
            log.info("删除运维端tokenList：{}", userKey);
        }
        log.info("[{}]-{}", userTokenList.size(), userKey);
        for (String userToken : userTokenList) {
            redisService.delToList(userKey, userToken);
            redisService.del(userToken);
        }
    }


    /**
     * @description: 根据品牌id获取当前用户能看到的所有用户（管理员和品牌能看到该品牌下的所有用户，加盟商能看到加盟商级别和区域级别的用户，区域用户只能看到区域级别的用户）
     * @author: mo.shanyong
     * @date: 2025/2/26 15:52
     * @param: brandId 品牌id
     * @param: info 当前用户
     * @return: java.util.List<com.tbit.uqbike.object.pojo.AccountUser>
     */
    @Override
    public List<AccountUser> getAUserByBrandAndUser(Integer brandId, LoginInfo info) {
        //当前登录账号是否绑定区域
        List<Account> accountList = holderAccountBoundService.getAccountByUserId(info.getAccountUserId());
        if (CollectionUtil.isNotEmpty(accountList)) {
            return accountUserDao.getByAccountIds(accountList.stream().map(Account::getAccountId).collect(Collectors.toList()));
        }
        //获取能查看的所有的账户id
        List<Integer> allAccountIdList = this.getAllAccountId(brandId, info);
        //获取账号信息
        return accountUserDao.getByAccountIds(allAccountIdList);
    }

    /**
     * @description: 根据B端用户id批量获取用户
     * @author: mo.shanyong
     * @date: 2025/4/10 9:04
     * @param: accountUserIdSet B端用户信息
     * @return: com.tbit.uqbike.object.pojo.AccountUser
     */
    @Override
    public List<AccountUser> getAccountUserByIds(Set<Integer> accountUserIdSet) {
        return accountUserDao.getAccountUserByIds(new ArrayList<>(accountUserIdSet));
    }

    @Override
    public PageInfo<AccountUserDTO> getAccountUserList(LoginInfo loginInfo, Integer brandId, Integer subRoleType,
                                                       String phone, String name, Integer accountId, Integer pageNo, Integer pageSize) {
        if (Objects.equals(subRoleType, UserConstant.USER_BRAND)
                || Objects.equals(subRoleType, UserConstant.USER_FRANCHISEE)
                || Objects.equals(subRoleType, UserConstant.USER_AGENT)) {
            PageInfo<AccountUserDTO> pageInfo = getAccountUserListExt(brandId, subRoleType, phone, name, accountId,
                    pageNo, pageSize);
            padGeoRegion(pageInfo.getList());
            return pageInfo;
        }

        subRoleType = roleIdToSubRoleType(subRoleType);

        List<AccountUserBound> accountUserBoundList = accountUserDao.getByAccountUserId(loginInfo.getAccountUserId());
        AccountUserBound accountUserBound = accountUserBoundList.get(0);
        List<Integer> accountIdList = new ArrayList<>();
        if (accountId == null) {
            if (loginInfo.roleIsAdmin()) {
                accountIdList = getAccountIdListByType(loginInfo.type, brandId);
            } else {
                accountIdList = getAccountIdListByType(loginInfo.type, accountUserBound.getAccountId());
            }
        } else {
            accountIdList.add(accountId);
        }
        PageHelper.startPage(pageNo, pageSize);
        List<AccountUserDTO> accountUserList = accountUserDao.getAccountUserListNew(accountIdList, subRoleType, phone, name);
        PageInfo<AccountUserDTO> pageInfo = new PageInfo<>(accountUserList);
        List<AccountUserDTO> accountUserDTOList = pageInfo.getList();
        //填充分区
        padGeoRegion(accountUserDTOList);
        return pageInfo;

    }

    private void padGeoRegion(List<AccountUserDTO> accountUserDTOList) {
        if (CollectionUtil.isEmpty(accountUserDTOList)){
            return;
        }
        List<Integer> accountUserIdList = accountUserDTOList.stream().map(AccountUserDTO::getAccountUserId).collect(Collectors.toList());
        List<AccountUserDTO> accountUserDTOListTemp = geoRegionDao.selectBatchByAccountUserId(accountUserIdList);
        if (CollectionUtil.isEmpty(accountUserDTOListTemp)){
            return;
        }
        Map<Integer, List<GeoRegion>> geoRegionMap = accountUserDTOListTemp.stream()
                .collect(Collectors.toMap(AccountUserDTO::getAccountUserId, AccountUserDTO::getGeoRegions));

        for (AccountUserDTO accountUserDTO : accountUserDTOList) {
            accountUserDTO.setGeoRegions(geoRegionMap.get(accountUserDTO.getAccountUserId()));
        }
    }

    /**
     * 历史遗留问题-角色转换 角色id转账号角色绑定表_subRoleType
     * 账号角色绑定表_subRoleType字段_子级角色类型0 表示跟主权限一致，0是默认值 1 表示区域运维管理员 2 表示区域运维人员 3 表示区域客服
     * 前端传 4转为1 5转为2 区域客服暂时没有
     */
    private Integer roleIdToSubRoleType(Integer subRoleType) {
        if (subRoleType == null){
            return null;
        }
        switch (subRoleType){
            case 4:
                return 1;
            case 5:
                return 2;
            default:
                return subRoleType;
        }
    }

    /**
     * 历史遗留问题-角色转换 账号角色绑定表_subRoleType转角色id
     * 账号角色绑定表_subRoleType字段_子级角色类型0 表示跟主权限一致，0是默认值 1 表示区域运维管理员 2 表示区域运维人员 3 表示区域客服
     *  subRoleType=1 -> roleId=4 subRoleType=2 -> roleId=5 区域客服暂时没有
     */
    private Integer subRoleTypeToRoleId(Integer subRoleType) {
        if (subRoleType == null){
            return null;
        }
        switch (subRoleType){
            case 1:
                return 4;
            case 2:
                return 5;
            default:
                return subRoleType;
        }
    }

    @Override
    public Boolean checkViewRoleAccountPermission(Integer roleId, LoginInfo loginInfo) {
        if (loginInfo.roleIsAdmin()){
            return true;
        }

        AccountUser accountUser = accountService.getAccountUserInfoById(loginInfo);
        Integer loginUserRoleId = null;
        if (accountUser.getSubRoleType() == 0){
            loginUserRoleId = loginInfo.getType();
        }else {
            loginUserRoleId = accountUser.getSubRoleType();
        }
        Role loginUserRole = roleService.selectRoleById(loginUserRoleId);
        Role role = roleService.selectRoleById(roleId);
        if (loginUserRole.getAccountId() != 0 && role.getAccountId() == 0){
            return false;
        }

        return Integer.parseInt(loginUserRole.getRoleLevel()) <= Integer.parseInt(role.getRoleLevel());
    }

    public PageInfo<AccountUserDTO> getAccountUserListExt(Integer brandId, Integer subRoleType, String phone, String name,
                                                          Integer accountId, Integer pageNo, Integer pageSize) {
        List<Integer> accountIdList = new ArrayList<>();

        if (Objects.equals(subRoleType, UserConstant.USER_BRAND)) {
            accountIdList = CollectionUtil.newArrayList(brandId);
        }
        if (Objects.equals(subRoleType, UserConstant.USER_FRANCHISEE)) {
            accountIdList = accountDao.listByParentId(brandId).stream()
                    .map(Account::getAccountId).collect(Collectors.toList());
        }
        if (Objects.equals(subRoleType, UserConstant.USER_AGENT)) {
            accountIdList = accountDao.selectByIdAndType(brandId, UserConstant.USER_BRAND).stream()
                    .map(Account::getAccountId).collect(Collectors.toList());
        }
        /**如果根据区域id筛选*/
        List<AccountUserDTO> accountUserList = null;
        if (accountId != null) {
            PageHelper.startPage(pageNo, pageSize);
            accountIdList = CollectionUtil.newArrayList(accountId);
            accountUserList = accountUserDao.getAccountUserListNew(accountIdList, 0, phone, name);
        } else {
            PageHelper.startPage(pageNo, pageSize);
            accountUserList = accountUserDao.getAccountUserListNew(accountIdList, 0, phone, name);
        }
        PageInfo<AccountUserDTO> pageInfo = new PageInfo<>(accountUserList);
        return pageInfo;
    }

    /**
     * 根据账号等级和(品牌id 或加盟商id 或区域id)获取所有accountId
     *
     * @param type      账号等级 0：管理员 1：品牌 2：加盟商 3：区域
     * @param accountId 品牌id 或加盟商id 或区域id
     */
    private List<Integer> getAccountIdListByType(Integer type, Integer accountId) {
        List<Integer> accountIdList = new ArrayList<>();
        if (Objects.equals(type, UserConstant.USER_ADMIN) || Objects.equals(type, UserConstant.USER_BRAND)) {
            accountIdList = accountDao.getAllId(accountId);
        }
        if (Objects.equals(type, UserConstant.USER_FRANCHISEE)) {
            accountIdList = accountDao.getChildAccountById(accountId, 0).stream()
                    .map(Account::getAccountId).collect(Collectors.toList());
            accountIdList.add(accountId);
        }
        if (Objects.equals(type, UserConstant.USER_AGENT)) {
            accountIdList = CollectionUtil.newArrayList(accountId);
        }
        return accountIdList;
    }

    /**
     * @description: 根据品牌id获取所有的区域的、加盟商的id
     * @author: mo.shanyong
     * @date: 2025/2/24 17:25
     * @param: brandId 品牌id
     * @return: java.util.List<java.lang.Integer>
     */
    private List<Integer> getAllAccountId(Integer brandId, LoginInfo info) {
        if (UserConstant.USER_ADMIN.equals(info.type) || UserConstant.USER_BRAND.equals(info.type)) {
            //获取全部的id(品牌id、加盟商id、区域id)
            return accountDao.getAllId(brandId);
        } else if (UserConstant.USER_FRANCHISEE.equals(info.type)) {//加盟商账户可以获取所有加盟商和区域的用户
            //加盟商Id
            List<Integer> allIdList = accountDao.getAccountByParentId(brandId);
            if (CollectionUtils.isNotEmpty(allIdList)) {
                //区域id
                List<Integer> accountIdList = accountDao.getAllAccountIdByIds(allIdList);
                allIdList.addAll(accountIdList);
            }
            return allIdList;
        }
        //区域用户只能获取所有的区域用户
        return accountDao.getAllAccountIdByIds(Collections.singletonList(brandId));
    }
}
